#!/usr/bin/python
#
# Copyright (C) 2011 Impact Dashboard
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#	  http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


from impact import widget
import logging
import random
import datetime
from impact.widget import WidgetDefinition
import urllib
import urllib2


from google.appengine.ext import db


import xpath
from xml.dom import minidom
from impact.platform import ImpactException
from google.appengine.api import urlfetch
import impact.authorization
from django.utils import simplejson as json

class facebook_get_friends(WidgetDefinition):

	def get_connections(self):
		#have to use long form when scopes are present for now
		return [{'name':'Facebook',
				'type':WidgetDefinition.CONNECTION_TYPE_FACEBOOK,
				'scopes':['offline_access','read_stream'],
				}]

	def get_data(self,api,selector_values,props):
		friends = api.call('/me/friends')
		return { 'value': len(friends['data']) }


class facebook_get_my_posts(WidgetDefinition):

	def get_connections(self):
		return [{'name':'Facebook',
				'type':WidgetDefinition.CONNECTION_TYPE_FACEBOOK,
				'scopes':['manage_pages'],
				}]

	def get_service_selector_names(self):
		return ['pages']

	def get_selector_data(self,api,name,selector_values):
		dict = api.call('/me/accounts')
		page_names = []
		page_ids 	= []

		for e in dict['data']:
			logging.info('facebook_get_my_posts get_selector_data -> '+str(e))
			if 'name' in e:
				page_names.append(e['name'])
			else:
				page_names.append('me')
			page_ids.append(e['id'])

		return page_names,page_ids


	def get_data(self,api,selector_values,props):
		dict = api.call('/'+selector_values['pages']+'/posts&limit=2000')
		#logging.info('facebook_get_my_posts get_data -> '+str(dict['data']))
			
		post_msg = []
		post_ids 	= []
		
		for e in dict['data']:
			if 'message' in e:
				post_msg.append(e['message'])
				post_ids.append(e['id'])
				
		
		#logging.info('facebook_get_my_posts get_message -> '+str(post_msg)+'count----'+str(count)+'---elsecount----'+str(elsecount))
			
		#return dict
		return {'value':len(post_ids)
			}

class facebook_get_comments(WidgetDefinition):

	def get_connections(self):
		return [{'name':'Facebook',
				'type':WidgetDefinition.CONNECTION_TYPE_FACEBOOK,
				'scopes':['manage_pages'],
				}]

	def get_service_selector_names(self):
		return ['pages']

	def get_selector_data(self,api,name,selector_values):
		dict = api.call('/me/accounts')
		page_names = []
		page_ids 	= []

		for e in dict['data']:
			logging.info('facebook_get_my_posts get_selector_data -> '+str(e))
			if 'name' in e:
				page_names.append(e['name'])
			else:
				page_names.append('me')
			page_ids.append(e['id'])

		return page_names,page_ids


	def get_data(self,api,selector_values,props):
		dict = api.call('/'+selector_values['pages']+'/posts&limit=20000')
		#logging.info('facebook_get_my_posts get_data -> '+str(dict['data']))
			
		#post_comments = []
		count=[]
		count=0
		
		for e in dict['data']:
			if 'comments' in e:
				#post_comments.append(e['comments']['count'])
				count=count+(e['comments']['count'])
				
		
		#logging.info('facebook_get_my_posts get_comments -> '+str(post_comments)+'count----'+str(count))#+'---elsecount----'+str(elsecount))
			
		#return dict
		return {'value':count
			}

class facebook_get_fan_posts(WidgetDefinition):

	def get_connections(self):
		return [{'name':'Facebook',
				'type':WidgetDefinition.CONNECTION_TYPE_FACEBOOK,
				'scopes':['manage_pages'],
				}]

	def get_service_selector_names(self):
		return ['pages']

	def get_selector_data(self,api,name,selector_values):
		dict = api.call('/me/accounts')
		page_names = []
		page_ids 	= []

		for e in dict['data']:
			logging.info('facebook_get_my_posts get_selector_data -> '+str(e))
			if 'name' in e:
				page_names.append(e['name'])
			else:
				page_names.append('me')
			page_ids.append(e['id'])

		return page_names,page_ids


	def get_data(self,api,selector_values,props):
		dict = api.call('/'+selector_values['pages']+'/feed&limit=20000')
		#logging.info('facebook_get_my_posts get_data -> '+str(dict['data']))
			
		#post_comments = []
		count=[]
		count=0
		
		for e in dict['data']:
			if ((e['from']['id']) != selector_values['pages']) and ((e['type']) == 'status') :
				#post_comments.append(e['comments']['count'])
				count=count+1
				
		
		#logging.info('facebook_get_my_posts get_comments -> '+str(post_comments)+'count----'+str(count))#+'---elsecount----'+str(elsecount))
			
		#return dict
		return {'value':count
			}

class facebook_get_page_views(WidgetDefinition):

	def get_connections(self):
		return [{'name':'Facebook',
				'type':WidgetDefinition.CONNECTION_TYPE_FACEBOOK,
				'scopes':['read_insights'],
				}]

	def get_service_selector_names(self):
		return ['pages']

	def get_selector_data(self,api,name,selector_values):
		dict = api.call('/me/accounts')
		page_names = []
		page_ids 	= []

		for e in dict['data']:
			logging.info('facebook_get_my_posts get_selector_data -> '+str(e))
			if 'name' in e:
				page_names.append(e['name'])
			else:
				page_names.append('me')
			page_ids.append(e['id'])

		return page_names,page_ids


	def get_data(self,api,selector_values,props):
		dict = api.call('/'+selector_values['pages']+'/insights/page_stream_views/day')
			
		
		page_views=[]
		for e in dict['data']:
				page_views.append(e['values'])
		#logging.info('facebook_get_page_views views -> '+str(dd[0][2]['value']))#+'count----'+str(count))#+'---elsecount----'+str(elsecount))
			
		return {'value':page_views[0][2]['value']
			}


class facebook_get_page_likes(WidgetDefinition):

	def get_connections(self):
		return [{'name':'Facebook',
				'type':WidgetDefinition.CONNECTION_TYPE_FACEBOOK,
				'scopes':['manage_pages'],
				}]

	def get_service_selector_names(self):
		return ['pages']

	def get_selector_data(self,api,name,selector_values):
		dict = api.call('/me/accounts')
		page_names = []
		page_ids 	= []

		for e in dict['data']:
			logging.info('facebook_get_page_likes get_selector_data -> '+str(e))
			if 'name' in e:
				page_names.append(e['name'])
			else:
				page_names.append('me')
			page_ids.append(e['id'])

		return page_names,page_ids


	def get_data(self,api,selector_values,props):
		dict = api.call('/'+selector_values['pages'])
		logging.info('facebook_get_page_likes get_data -> '+str(dict))

		#return dict
		return {'value':dict['likes'],
				'title':dict['name']
				}


class facebook_get_album_likes(WidgetDefinition):

	def get_connections(self):
		return [{'name':'Facebook',
				'type':WidgetDefinition.CONNECTION_TYPE_FACEBOOK,
				'scopes':['user_photos'],
				}]

	def get_service_selector_names(self):
		return ['albums','picture']

	def get_selector_data(self,api,name,selector_values):
		if name == 'albums':
			dict = api.call('/me/albums')
			page_names = []
			page_ids   = []
			for e in dict['data']:
				page_names.append(e['name'])
				page_ids.append(e['id'])
			return page_names,page_ids
#		elif name == 'picture':
#			dict = api.call('/'+selector_values['albums']) ##TODO verify api call
#			picture_names = []
#			picture_ids   = []
#			for e in dict['pictures']: ##TODO verify api call
#				picture_names.append(e['name']) ##etc
#				picture_ids.append(e['id']) ##etc
#			return picture_names,picture_ids
		elif name == 'picture':
			return ["xx"],["a picture"]


	def get_data(self,api,selector_values,props):
		##dict= api.call('/'+selector_values['picture'])
		total_likes= api.call('/'+selector_values['picture']+'/likes')

		#return dict
		return {'value':len(total_likes['data']),
				'title':dict['name']
				}

class facebook_get_video_likes(WidgetDefinition):

	def get_connections(self):
		return [{'name':'Facebook',
				'type':WidgetDefinition.CONNECTION_TYPE_FACEBOOK,
				'scopes':['user_videos', 'friends_videos'],
				}]

	def get_service_selector_names(self):
		return ['videos']

	def get_selector_data(self,api,name,selector_values):
		dict = api.call('/me/videos')
		page_names = []
		page_ids 	= []

		for e in dict['data']:
			page_names.append(e['name'])
			page_ids.append(e['id'])

		return page_names,page_ids


	def get_data(self,api,selector_values,props):
		dict= api.call('/'+selector_values['videos'])
		total_likes= api.call('/'+selector_values['videos']+'/likes')

		#return dict
		return {'value':len(total_likes['data']),
				'title':dict['name']
				}


class twitter_get_followers(WidgetDefinition):

	def get_connections(self):
		return [WidgetDefinition.CONNECTION_TYPE_TWITTER]

	def get_data(self,api,selector_values,props):
		twitter_user_data = api.call('/account/verify_credentials')

		return { 'value': twitter_user_data['followers_count'] }

	def get_props_editor(self):
		return WidgetDefinition.PROPS_EDITOR_TYPE_BASIC

class twitter_get_tweets(WidgetDefinition):

	def get_connections(self):
		return [WidgetDefinition.CONNECTION_TYPE_TWITTER]

	def get_data(self,api,selector_values,props):
		twitter_user_data = api.call('/account/verify_credentials')
		#twitter_user_tweets = api.call('/statuses/user_timeline',{'id':twitter_user_data['id']})
		twitter_user_tweets = api.call('/users/show',{'id':twitter_user_data['id']})

		#user_tweets=[]
		#user_tweets.append(twitter_user_tweets['statuses_count'])

		#for e in twitter_user_tweets:
		#	user_tweets.append(e['text'])


		return { 'value': twitter_user_tweets['statuses_count']}

	def get_props_editor(self):
		return WidgetDefinition.PROPS_EDITOR_TYPE_BASIC


class twitter_get_mentions(WidgetDefinition):

	def get_connections(self):
		return [WidgetDefinition.CONNECTION_TYPE_TWITTER]

	def get_data(self,api,selector_values,props):
		twitter_user_data = api.call('/account/verify_credentials')
		twitter_user_mentions = api.call('/statuses/mentions',{'id':twitter_user_data['id']})

		user_mentions=[]

		for e in twitter_user_mentions:
			user_mentions.append(e['text'])


		return { 'value': user_mentions}

	def get_props_editor(self):
		return WidgetDefinition.PROPS_EDITOR_TYPE_BASIC

class twitter_get_retweets(WidgetDefinition):

	def get_connections(self):
		return [WidgetDefinition.CONNECTION_TYPE_TWITTER]

	def get_data(self,api,selector_values,props):
		twitter_user_data = api.call('/account/verify_credentials')
		twitter_user_retweets = api.call('/statuses/retweets_of_me',{'id':twitter_user_data['id']})

		user_retweets=[]

		for e in twitter_user_retweets:
			user_retweets.append(e['text'])


		return { 'value': user_retweets}

	def get_props_editor(self):
		return WidgetDefinition.PROPS_EDITOR_TYPE_BASIC

#WARNING- no real function to do this with twitter, so we have to keep calling & calling
# not the greatest way to do stuff
# if there was a way to search within a time range (new hashtag refs from yesterday to today) this would be better...
# even better would be a function to return a count per day
class twitter_get_hashtag_search(WidgetDefinition):

	MAX_COUNT = 1000
	
	def get_connections(self):
		return [WidgetDefinition.CONNECTION_TYPE_TWITTER]

	def get_data(self,api,selector_values,props):
		#twitter_user_tweets = api.call('search.json?q='+props['input'],{'id':api.profile['uid']})
		base_url = 'http://search.twitter.com/search.json'
		init_args = '?rpp=100&result_type=recent&q='+urllib.quote_plus(selector_values['hashtag'])
		dict = get_json2(base_url+init_args)
		count = len(dict['results'])
		while count < self.MAX_COUNT and len(dict['results']) == dict['results_per_page']:
			dict = get_json2(base_url+dict['next_page'])
			count += len(dict['results'])
		return { 'value': count}
	
	def get_service_selector_names(self):
		return ['hashtag']
	
	def get_service_selector_types(self):
		return [WidgetDefinition.SELECTOR_TYPE_FREE_TEXT]

	def get_props_editor(self):
		return WidgetDefinition.PROPS_EDITOR_TYPE_BASIC



class twitter_something(WidgetDefinition):

	def get_connections(self):
		return [WidgetDefinition.CONNECTION_TYPE_TWITTER]

	def get_data(self,api,selector_values,props):
		#TODO page apply
		followers = api.call('/followers/ids')
		for fid in followers:
			user_info = api.call('/users/show',{'user_id':fid})
			if user_info.has_key('status'):
				status = user_info['status']
				if (status.has_key('geo')):
					geo = status['geo']
					logging.info(str(geo))
				else:
					logging.info('no geo '+str(user_info))
			else:
				logging.info('no status '+str(user_info))
		return { 'value': 0 }

	def get_props_editor(self):
		return WidgetDefinition.PROPS_EDITOR_TYPE_BASIC


# All Google Widget related classes

class google_analytics_get_page_views(WidgetDefinition):

	def get_connections(self):
		return [WidgetDefinition.CONNECTION_TYPE_GOOGLE_ANALYTICS]

	def get_service_selector_names(self):
		return ['account']

	def get_selector_data(self,api,name,selector_values):
		dict = api.call('/accounts/default')
		account_names = []
		account_ids 	= []
		for e in dict['feed']['entry']:
			account_ids.append(e['dxp$tableId']['$t'])
			account_names.append(e['title']['$t'])
		return  account_names,account_ids

	def get_data(self,api,selector_values,props):
		yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
		start_date = yesterday.strftime('%Y-%m-%d')
		end_date   = start_date

		dict = api.call('/data',
							{'ids':selector_values['account'],
							'metrics':'ga:pageviews',
							'start-date':start_date,
							'end-date':end_date
							})

		return {'value':dict['feed']['dxp$aggregates']['dxp$metric'][0]['value'],
				'title':dict['feed']['dxp$dataSource'][0]['dxp$tableName']['$t'],
				'date':start_date}

class google_analytics_get_site_visit(WidgetDefinition):

	def get_connections(self):
		return [WidgetDefinition.CONNECTION_TYPE_GOOGLE_ANALYTICS]

	def get_service_selector_names(self):
		return ['account']

	def get_selector_data(self,api,name,selector_values):
		dict = api.call('/accounts/default')
		account_names = []
		account_ids 	= []
		for e in dict['feed']['entry']:
			account_ids.append(e['dxp$tableId']['$t'])
			account_names.append(e['title']['$t'])
		return  account_names,account_ids

	def get_data(self,api,selector_values,props):
		yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
		start_date = yesterday.strftime('%Y-%m-%d')
		end_date   = start_date

		dict = api.call('/data',
							{'ids':selector_values['account'],
							'dimensions':'ga:longitude,ga:latitude,ga:city',
							'metrics':'ga:visitors',
							'start-date':start_date,
							'end-date':end_date
							})
		geo_values=[]
		
		for e in dict['feed']['entry']:
			geo_cord ={'longitude' : e['dxp$dimension'][0]['value'],'latitude' :e['dxp$dimension'][1]['value'], 'scale':e['dxp$metric'][0]['value'] }
			geo_values.append(geo_cord)
			
		
		#return {'value':dict['feed']['dxp$aggregates']['dxp$metric'][0]['value'],		
		return {'value':dict['feed']['dxp$aggregates']['dxp$metric'][0]['value'],
				'title':dict['feed']['dxp$dataSource'][0]['dxp$tableName']['$t'],
				'date':start_date,
				'geo_values':geo_values}

class google_analytics_get_page_per_visit(WidgetDefinition):

	def get_connections(self):
		return [WidgetDefinition.CONNECTION_TYPE_GOOGLE_ANALYTICS]

	def get_service_selector_names(self):
		return ['account']

	def get_selector_data(self,api,name,selector_values):
		dict = api.call('/accounts/default')
		account_names = []
		account_ids 	= []
		for e in dict['feed']['entry']:
			account_ids.append(e['dxp$tableId']['$t'])
			account_names.append(e['title']['$t'])
		return  account_names,account_ids

	def get_data(self,api,selector_values,props):
		yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
		start_date = yesterday.strftime('%Y-%m-%d')
		end_date   = start_date

		dict = api.call('/data',
							{'ids':selector_values['account'],
							'metrics':'ga:pageviewsPerVisit',
							'start-date':start_date,
							'end-date':end_date
							})

		return {'value':dict['feed']['dxp$aggregates']['dxp$metric'][0]['value'],
				'title':dict['feed']['dxp$dataSource'][0]['dxp$tableName']['$t'],
				'date':start_date}

class google_analytics_get_bounce_rate(WidgetDefinition):

	def get_connections(self):
		return [WidgetDefinition.CONNECTION_TYPE_GOOGLE_ANALYTICS]

	def get_service_selector_names(self):
		return ['account']

	def get_selector_data(self,api,name,selector_values):
		dict = api.call('/accounts/default')
		account_names = []
		account_ids 	= []
		for e in dict['feed']['entry']:
			account_ids.append(e['dxp$tableId']['$t'])
			account_names.append(e['title']['$t'])
		return  account_names,account_ids

	def get_data(self,api,selector_values,props):
		yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
		start_date = yesterday.strftime('%Y-%m-%d')
		end_date   = start_date

		dict = api.call('/data',
							{'ids':selector_values['account'],
							'metrics':'ga:visitBounceRate',
							'start-date':start_date,
							'end-date':end_date
							})

		return {'value':dict['feed']['dxp$aggregates']['dxp$metric'][0]['value'],
				'title':dict['feed']['dxp$dataSource'][0]['dxp$tableName']['$t'],
				'date':start_date}

class google_analytics_get_referrers(WidgetDefinition):
	#this means the data doesn't go in the database
	#when you call get data for widget it just calls through
	def is_live_data_widget(self):
		return True

	def get_connections(self):
		return [WidgetDefinition.CONNECTION_TYPE_GOOGLE_ANALYTICS]

	def get_service_selector_names(self):
		return ['account']

	def get_selector_data(self,api,name,selector_values):
		dict = api.call('/accounts/default')
		account_names = []
		account_ids 	= []
		for e in dict['feed']['entry']:
			account_ids.append(e['dxp$tableId']['$t'])
			account_names.append(e['title']['$t'])
		return  account_names,account_ids

	def get_data(self,api,selector_values,props):
		yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
		start_date = yesterday.strftime('%Y-%m-%d')
		end_date   = start_date

		dict = api.call('/data',
							{'ids':selector_values['account'],
							'dimensions':'ga:source',
							'metrics':'ga:visitors',
							'sort':'-ga:visitors',
							'start-date':start_date,
							'end-date':end_date,
							'max-results':5
							})
		referrers=[]
		for e in dict['feed']['entry']:
			referrers.append(e['dxp$dimension'][0]['value'])

		return {'value':referrers,
				'title':dict['feed']['dxp$dataSource'][0]['dxp$tableName']['$t'],
				'date':start_date}

class google_analytics_get_absolute_unique_visitors(WidgetDefinition):

	def get_connections(self):
		return [WidgetDefinition.CONNECTION_TYPE_GOOGLE_ANALYTICS]

	def get_service_selector_names(self):
		return ['account']

	def get_selector_data(self,api,name,selector_values):
		dict = api.call('/accounts/default')
		account_names = []
		account_ids 	= []
		for e in dict['feed']['entry']:
			account_ids.append(e['dxp$tableId']['$t'])
			account_names.append(e['title']['$t'])
		return  account_names,account_ids

	def get_data(self,api,selector_values,props):
		yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
		start_date = yesterday.strftime('%Y-%m-%d')
		end_date   = start_date

		dict = api.call('/data',
							{'ids':selector_values['account'],
							'dimensions':'ga:visitCount',
							'metrics':'ga:visitors',
							'filters':'ga:visitCount==1',
							'sort':'ga:visitCount',
							'start-date':start_date,
							'end-date':end_date,
							})

		return {'value':dict['feed']['dxp$aggregates']['dxp$metric'][0]['value'],
				'title':dict['feed']['dxp$dataSource'][0]['dxp$tableName']['$t'],
				'date':start_date}

class google_analytics_get_percent_new_visits(WidgetDefinition):

	def get_connections(self):
		return [WidgetDefinition.CONNECTION_TYPE_GOOGLE_ANALYTICS]

	def get_service_selector_names(self):
		return ['account']

	def get_selector_data(self,api,name,selector_values):
		dict = api.call('/accounts/default')
		account_names = []
		account_ids 	= []
		for e in dict['feed']['entry']:
			account_ids.append(e['dxp$tableId']['$t'])
			account_names.append(e['title']['$t'])
		return  account_names,account_ids

	def get_data(self,api,selector_values,props):
		yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
		start_date = yesterday.strftime('%Y-%m-%d')
		end_date   = start_date

		dict = api.call('/data',
							{'ids':selector_values['account'],
							'metrics':'ga:percentNewVisits',
							'start-date':start_date,
							'end-date':end_date
							})

		return {'value':dict['feed']['dxp$aggregates']['dxp$metric'][0]['value'],
				'title':dict['feed']['dxp$dataSource'][0]['dxp$tableName']['$t'],
				'date':start_date}

class google_analytics_get_browsers(WidgetDefinition):

	def get_connections(self):
		return [WidgetDefinition.CONNECTION_TYPE_GOOGLE_ANALYTICS]

	def get_service_selector_names(self):
		return ['account']

	def get_selector_data(self,api,name,selector_values):
		dict = api.call('/accounts/default')
		account_names = []
		account_ids 	= []
		for e in dict['feed']['entry']:
			account_ids.append(e['dxp$tableId']['$t'])
			account_names.append(e['title']['$t'])
		return  account_names,account_ids

	def get_data(self,api,selector_values,props):
		yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
		start_date = yesterday.strftime('%Y-%m-%d')
		end_date   = start_date

		dict = api.call('/data',
							{'ids':selector_values['account'],
							'dimensions' : 'ga:browser',
							'metrics' : 'ga:visitors',
							'sort': '-ga:visitors',
							'start-date':start_date,
							'end-date':end_date,
							'max-results':5
							})
		browsers=[]
		for e in dict['feed']['entry']:
			browsers.append(e['dxp$dimension'][0]['value'])

		return {'value':browsers,
				'title':dict['feed']['dxp$dataSource'][0]['dxp$tableName']['$t'],
				'date':start_date}


class google_analytics_get_connection_speed(WidgetDefinition):

	def get_connections(self):
		return [WidgetDefinition.CONNECTION_TYPE_GOOGLE_ANALYTICS]

	def get_service_selector_names(self):
		return ['account']

	def get_selector_data(self,api,name,selector_values):
		dict = api.call('/accounts/default')
		account_names = []
		account_ids 	= []
		for e in dict['feed']['entry']:
			account_ids.append(e['dxp$tableId']['$t'])
			account_names.append(e['title']['$t'])
		return  account_names,account_ids

	def get_data(self,api,selector_values,props):
		yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
		start_date = yesterday.strftime('%Y-%m-%d')
		end_date   = start_date

		dict = api.call('/data',
							{'ids':selector_values['account'],
							'dimensions' : 'ga:connectionSpeed',
							'metrics' : 'ga:visitors',
							'sort': '-ga:visitors',
							'start-date':start_date,
							'end-date':end_date,
							'max-results':5
							})
		connection_speed=[]
		for e in dict['feed']['entry']:
			connection_speed.append(e['dxp$dimension'][0]['value'])

		return {'value':connection_speed,
				'title':dict['feed']['dxp$dataSource'][0]['dxp$tableName']['$t'],
				'date':start_date}


class google_analytics_get_avg_time_on_site(WidgetDefinition):

	def get_connections(self):
		return [WidgetDefinition.CONNECTION_TYPE_GOOGLE_ANALYTICS]

	def get_service_selector_names(self):
		return ['account']

	def get_selector_data(self,api,name,selector_values):
		dict = api.call('/accounts/default')
		account_names = []
		account_ids 	= []
		for e in dict['feed']['entry']:
			account_ids.append(e['dxp$tableId']['$t'])
			account_names.append(e['title']['$t'])
		return  account_names,account_ids

	def get_data(self,api,selector_values,props):
		yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
		start_date = yesterday.strftime('%Y-%m-%d')
		end_date   = start_date

		dict = api.call('/data',
							{'ids':selector_values['account'],
							'metrics':'ga:avgTimeOnSite',
							'start-date':start_date,
							'end-date':end_date
							})

		return {'value':dict['feed']['dxp$aggregates']['dxp$metric'][0]['value'],
				'title':dict['feed']['dxp$dataSource'][0]['dxp$tableName']['$t'],
				'date':start_date}


class you_tube_get_views(WidgetDefinition):

	def get_connections(self):
		return [WidgetDefinition.CONNECTION_TYPE_YOUTUBE]

	def get_service_selector_names(self):
		return ['video']

	def get_selector_data(self,api,name,selector_values):
		dict = api.call("/users/"+api.profile['username']+"/uploads")
		video_names = []
		video_ids 	= []
		for e in dict['feed']['entry']:
			video_ids.append(e['id']['$t'].split(':')[-1])
			video_names.append(e['title']['$t'])
		return video_names,video_ids

	def get_data(self,api,selector_values,props):
		dict = api.call('/videos/'+selector_values['video'])
		return {'count':dict['entry']['yt$statistics']['viewCount'],
				'value':dict['entry']['yt$statistics']['viewCount'],
				'title':dict['entry']['title']['$t'],
				'thumb':dict['entry']['media$group']['media$thumbnail'][0]['url']}


#class you_tube_get_channel_views(WidgetDefinition):

#	def get_connections(self):
#		return [WidgetDefinition.CONNECTION_TYPE_YOUTUBE]

#	def get_service_selector_names(self):
#		return ['channels']

#	def get_selector_data(self,api,name,selector_values):
#		dict = api.call("/users/"+api.profile['username']+"/subscriptions")
#		channels_names = []
#		channels_ids 	= []
#		for e in dict['feed']['entry']:
#			channels_ids.append(e)
#			channels_names.append(e['title']['$t'])
#		return channels_names,channels_ids

#	def get_data(self,api,selector_values,props):
#		dict = api.call('/videos/'+selector_values['video'])
#		return {'count':dict['entry']['yt$statistics']['viewCount'],
#				'title':dict['entry']['title']['$t'],
#				'thumb':dict['entry']['media$group']['media$thumbnail'][0]['url']}

class you_tube_get_channel_views(WidgetDefinition):

	def get_connections(self):
		return [WidgetDefinition.CONNECTION_TYPE_YOUTUBE]

	def get_service_selector_names(self):
		return ['channel']

	def get_selector_data(self,api,name,selector_values):
		dict = api.call("/users/"+api.profile['username'])
		channel_names = []

		channel_names.append(dict['entry']['title']['$t'])
		return channel_names,0

	def get_data(self,api,selector_values,props):
		dict = api.call("/users/"+api.profile['username'])
		return {'count':dict['entry']['yt$statistics']['viewCount'],
			    'value':dict['entry']['yt$statistics']['viewCount'],
				'subscriber':dict['entry']['yt$statistics']['subscriberCount'],
				'title':dict['entry']['title']['$t'],
				'thumb':dict['entry']['media$thumbnail']['url']}

	#def get_props_editor(self):
	#	return WidgetDefinition.PROPS_EDITOR_TYPE_INPUT_BOX


class you_tube_get_channel_subscribers(WidgetDefinition):

	def get_connections(self):
		return [WidgetDefinition.CONNECTION_TYPE_YOUTUBE]

	def get_service_selector_names(self):
		return ['channel']

	def get_selector_data(self,api,name,selector_values):
		dict = api.call("/users/"+api.profile['username'])
		channel_names = []

		channel_names.append(dict['entry']['title']['$t'])
		return channel_names,0

	def get_data(self,api,selector_values,props):
		dict = api.call("/users/"+api.profile['username'])
		return {'count':dict['entry']['yt$statistics']['viewCount'],
				'value':dict['entry']['yt$statistics']['viewCount'],
				'subscriber':dict['entry']['yt$statistics']['subscriberCount'],
				'title':dict['entry']['title']['$t'],
				'thumb':dict['entry']['media$thumbnail']['url']}

	#def get_props_editor(self):
	#	return WidgetDefinition.PROPS_EDITOR_TYPE_INPUT_BOX




class vimeo_get_views(WidgetDefinition):

	def get_connections(self):
		return [WidgetDefinition.CONNECTION_TYPE_VIMEO]

	def get_service_selector_names(self):
		return ['video']

	def get_selector_data(self,api,name,selector_values):
		dict = api.call('vimeo.videos.getAll',{'user_id':api.profile['uid'],'page':'1','per_page':'50','sort':'newest'})
		video_names = []
		video_ids 	= []
		for v in dict['videos']['video']:
			video_ids.append(v['id'])
			video_names.append(v['title'])
		return video_names,video_ids

	def get_data(self,api,selector_values,props):
		dict = api.call('vimeo.videos.getInfo',{'video_id':selector_values['video']})
		return {'count':dict['video'][0]['number_of_plays'],
				'value':dict['video'][0]['number_of_plays'],
				'title':dict['video'][0]['title'],
				'thumb':dict['video'][0]['thumbnails']['thumbnail'][0]['_content']}


class vimeo_get_channel_views(WidgetDefinition):

	def get_connections(self):
		return [WidgetDefinition.CONNECTION_TYPE_VIMEO]

	def get_service_selector_names(self):
		return ['channel']

	def get_selector_data(self,api,name,selector_values):
		dict = api.call('vimeo.channels.getAll',{'user_id':api.profile['uid'],'page':'1','per_page':'50','sort':'newest'})
		channel_names = []
		channel_ids = []

		if dict['channels'].has_key('channel'):
			#vimeo has a non standard way of returning channels so we need to test for type
			#is it a list of channels
			if isinstance(dict['channels']['channel'], list):
				for e in dict['channels']['channel']:
					channel_ids.append(e['id'])
					channel_names.append(e['name'])
			#or is it a single channel
			else:
				e = dict['channels']['channel']
				channel_ids.append(e['id'])
				channel_names.append(e['name'])

		return channel_names,channel_ids

	def get_data(self,api,selector_values,props):

		### TODO
		# the same kind of testing (list) must occur here too
		dict = api.call('vimeo.channels.getInfo',{'channel_id':selector_values['channel']})

		return {'count':dict['channel']['total_subscribers'],
			    'value':dict['channel']['total_subscribers'],
				'name':dict['channel']['name'],
				'thumb':dict['channel']['logo_url']}







class custom_text(WidgetDefinition):

	def is_live_data_widget(self):
		return True

	def get_data(self,api,selector_values,props):
		return None

	def get_props_editor(self):
		return WidgetDefinition.PROPS_EDITOR_TYPE_TEXT



class custom_embed(WidgetDefinition):

	def is_live_data_widget(self):
		return True

	def get_data(self,api,selector_values,props):
		return None

	def get_props_editor(self):
		return WidgetDefinition.PROPS_EDITOR_TYPE_EMBED


#class custom_feed(WidgetDefinition):
#
#	def get_data(self,api,selector_values,props):
#		return None
#
#	def get_props_editor(self):
#		return WidgetDefinition.PROPS_EDITOR_TYPE_TEXT




class get_google_search_web(WidgetDefinition):

	def get_data(self,api,selector_values,props):

		url = ('https://ajax.googleapis.com/ajax/services/search/web?v=1.0&q='+props['text'])

		request = urllib2.Request(url, None, {'Referer':'http://www.google.com'})
		response = urllib2.urlopen(request)

		dict = json.load(response)

		search_title=[]
		search_url=[]

		for e in dict['responseData']['results']:
			search_title.append(e['title'])
			search_url.append(e['url'])

		return {'title':search_title, 'url':search_url}


	def get_props_editor(self):
		return WidgetDefinition.PROPS_EDITOR_TYPE_TEXT


class get_google_search_blog(WidgetDefinition):

	def get_data(self,api,selector_values,props):

		url = ('https://ajax.googleapis.com/ajax/services/search/blog?v=1.0&q='+props['text'])

		request = urllib2.Request(url, None, {'Referer':'http://www.google.com'})
		response = urllib2.urlopen(request)

		dict = json.load(response)

		search_title=[]
		search_url=[]

		for e in dict['responseData']['results']:
			search_title.append(e['title'])
			search_url.append(e['url'])

		return {'title':search_title, 'url':search_url}


	def get_props_editor(self):
		return WidgetDefinition.PROPS_EDITOR_TYPE_TEXT


class get_google_search_news(WidgetDefinition):

	def get_data(self,api,selector_values,props):

		url = ('https://ajax.googleapis.com/ajax/services/search/news?v=1.0&q='+props['text'])

		request = urllib2.Request(url, None, {'Referer':'http://www.google.com'})
		response = urllib2.urlopen(request)

		dict = json.load(response)

		search_title=[]
		search_url=[]

		for e in dict['responseData']['results']:
			search_title.append(e['title'])
			search_url.append(e['url'])

		return {'title':search_title, 'url':search_url}


	def get_props_editor(self):
		return WidgetDefinition.PROPS_EDITOR_TYPE_TEXT



class custom_manual_or_xml(WidgetDefinition):

	def get_data(self,api,selector_values,props):
		if props['custom-type']=='manual':
			if props.has_key('custom-count'):
				return {'value':props['custom-count']}
		elif props['custom-type']=='xml':
			xml_stream = urllib.urlopen(props['custom-feed-url'])
			xpath_num_expr = props['custom-xpath-num']
			xpath_geo_expr = props['custom-xpath-geo']
			values = []
			geo_values = []
			tree = minidom.parse(xml_stream)
			if xpath_num_expr is not None and xpath_num_expr != '':
				xpath_result = xpath.find(xpath_num_expr, tree)
				for r in xpath_result:
					v = self.get_node_value(r,xpath_num_expr)
					values.append(v)
			if xpath_geo_expr is not None and xpath_geo_expr != '':
				xpath_result = xpath.find(xpath_geo_expr, tree)
				logging.info(xpath_result)
				for r in xpath_result:
					v = self.get_node_value(r,xpath_geo_expr)
					#TODO normalize v - it should be a string with 2 number separated by comma
					#geo_values.append({ latitude: parse_float(v[0:s]), longitude: v[s,end] });
					geo_values.append(v)
			ret_dict = {}
			if len(values)==1:
				ret_dict['value']= values[0]
			elif len(values)>0:
				ret_dict['value'] = values
			if len(geo_values)!=0:
				ret_dict['geo_values'] = geo_values
			return ret_dict

	##TODO
	# lots of assumptions being made
	# lets figure out how to handle gathering the values in a simple way
	def get_node_value(self,node,xpath):
		using_attr = xpath.find('[@')
		if using_attr != -1:
			s = xpath.index('[@')+2
			e = xpath.index(']',s)
			attr = xpath[s:e]
			return node.attributes[attr].value
		elif node.hasChildNodes():
			return node.firstChild.nodeValue ##maybe should collect all text nodes below...
		else:
			raise ImpactException('cant get_node_value '+node+' '+xpath)

	def get_props_editor(self):
		return WidgetDefinition.PROPS_EDITOR_TYPE_CUSTOM

	def get_default_props(self):
			return {'custom-type':'manual'}

class impact_correlation(WidgetDefinition):

	def is_correlation(self):
		return True

	def get_data(self,api,selector_values,props):
		return None
		#ret_dict = {'corr':[]}
		#cc = db.get(wi.children)
		#for c in cc:
		#widget_data =  c.get_data()
		#ret_dict['corr'].append({'name':c.widget.name,'value':widget_data})
		#return ret_dict

	def get_props_editor(self):
		return WidgetDefinition.PROPS_EDITOR_TYPE_CORRELATION

	def get_default_props(self):
		return {'display-style':'total-pie'}

def make_http_request(url,headers=None,params=None,method=urlfetch.GET):
	if params == None:
		params = {}
	if headers == None:
		headers = {}

	for k,v in params:
		params[k] = urllib.quote(v)

	rpc = urlfetch.create_rpc(deadline=10.0)
	urlfetch.make_fetch_call(rpc, url, method=method, headers=headers)
	return rpc.status_code, rpc.content

def make_wrapped_http_request(url,headers=None,params=None,method=urlfetch.GET):
	response_code,response_content = make_http_request(url,headers,params,method)
	#not really much we can do in this case, they are either failing or being rate limited#
	if response_code != 200:
		raise ImpactException("Call to "+url+" failed. Response code was "+response_code+".Response content was "+response_content,impact.authorization.API_EXCEPTION_CODE_SERVICE_ERROR);
	return response_content

def make_wrapped_http_request_unpack_json(url,headers=None,params=None,method=urlfetch.GET):
	return json.loads(make_wrapped_http_request(url, headers, params, method))

def get_json2(url):
		request = urllib2.Request(url, None, {'Referer':'http://www.google.com'})
		response = urllib2.urlopen(request)
		return json.load(response, None)

